package paim.wingchun.testes;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
@SuppressWarnings("serial")

public class TreeWithPopup extends JPanel {

    DefaultMutableTreeNode root, node1, node2, node3;

    public TreeWithPopup() {
        MyJTree tree;
        root = new DefaultMutableTreeNode("root", true);
        node1 = new DefaultMutableTreeNode("node 1", true);
        node2 = new DefaultMutableTreeNode("node 2", true);
        node3 = new DefaultMutableTreeNode("node 3", true);
        root.add(node1);
        node1.add(node2);
        root.add(node3);
        setLayout(new BorderLayout());
        tree = new MyJTree(root);
        add(new JScrollPane((JTree) tree), "Center");
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }

    public static void main(String s[]) {
        JFrame frame = new JFrame("Tree With Popup");
        TreeWithPopup panel = new TreeWithPopup();

        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setForeground(Color.black);
        frame.setBackground(Color.lightGray);
        frame.getContentPane().add(panel, "Center");

        frame.setSize(panel.getPreferredSize());
        frame.setVisible(true);
        frame.addWindowListener(new WindowCloser());
    }
}


class WindowCloser extends WindowAdapter {

    @Override
    public void windowClosing(WindowEvent e) {
        Window win = e.getWindow();
        win.setVisible(false);
        System.exit(0);
    }
}


@SuppressWarnings("serial")
class MyJTree extends JTree implements ActionListener {

    JPopupMenu popup;

    JMenuItem mi;

    MyJTree(DefaultMutableTreeNode dmtn) {
        super(dmtn);
        // define the popup
        popup = new JPopupMenu();
        mi = new JMenuItem("Insert a children");
        mi.addActionListener(this);
        mi.setActionCommand("insert");
        popup.add(mi);
        mi = new JMenuItem("Remove this node");
        mi.addActionListener(this);
        mi.setActionCommand("remove");
        popup.add(mi);
        popup.setOpaque(true);
        popup.setLightWeightPopupEnabled(true);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    popup.show((JComponent)e.getSource(), e.getX(), e.getY());
                }
            }
            @Override
            public void mouseReleased(MouseEvent e) {
                if ( e.isPopupTrigger() ) {
                    popup.show((JComponent) e.getSource(), e.getX(), e.getY());
                }
            }
        });

    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        DefaultMutableTreeNode dmtn, node;

        TreePath path = this.getSelectionPath();
        dmtn = (DefaultMutableTreeNode) path.getLastPathComponent();
        if ( ae.getActionCommand().equals("insert") ) {
            node = new DefaultMutableTreeNode("children");
            dmtn.add(node);
            // thanks to Yong Zhang for the tip for refreshing the tree structure.
            ((DefaultTreeModel) this.getModel()).nodeStructureChanged((TreeNode) dmtn);
        }
        if ( ae.getActionCommand().equals("remove") ) {
            node = (DefaultMutableTreeNode) dmtn.getParent();
            // Bug fix by essam
            int nodeIndex = node.getIndex(dmtn); // declare an integer to hold the selected nodes index
            dmtn.removeAllChildren(); // remove any children of selected node
            node.remove(nodeIndex); // remove the selected node, retain its siblings
            ((DefaultTreeModel) this.getModel()).nodeStructureChanged((TreeNode) dmtn);
        }
    }
}
